package com.hulu73.struts1.newCore;

import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.hulu73.struts1.utils.RequestUtils;

/**
 * 处理请求(struts1所有的请求都使用同一控制器)
 * @author lzg
 *
 * 2017年9月11日
 */
public class RequestProcessor {
	
	public static final String INCLUDE_PATH_INFO =
	        "javax.servlet.include.path_info";
	
	 public static final String INCLUDE_SERVLET_PATH =
		        "javax.servlet.include.servlet_path";
	 
	 public static final String LOCALE_KEY = "com.hulu73.struts1.LOCALE";
	
	protected ActionMapping actionMapping = null;
    
    protected ActionServlet servlet = null;
    
    protected HashMap actions = new HashMap();
    
    public void init(ActionServlet actionServlet, ActionMapping actionMapping) {
		this.servlet = actionServlet;
		this.actionMapping = actionMapping;
	}

	public void process(HttpServletRequest request, HttpServletResponse response) throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException, ServletException {
		//获取请求路径
		String path = processPath(request, response);
		if (path == null) {
            return;
        }
		System.out.println("path===" + path);
		//设置国际化
		processLocale(request, response);
		
		/*设置头部信息
		 * processContent(request, response);
        processNoCache(request, response);*/
		
		ActionMapping mapping = processMapping(request, response, path);
		
		ActionForm form = processActionForm(request, response, mapping);
		
		
		Action action = processActionCreate(request, response, mapping);
		System.out.println("-------");
		
		ActionForward forward = processActionPerform(request, response, action, form, mapping);
		
		processForwardConfig(request, response, forward);
	}
	
	protected void processForwardConfig(HttpServletRequest request,
	        HttpServletResponse response, ActionForward forward)
	        throws IOException, ServletException {
		if (forward == null) {
            return;
        }
		String forwardPath = forward.getPath();
        String uri;
        
        /*if (forwardPath.startsWith("/")) {
            // get module relative uri
            uri = RequestUtils.forwardURL(request, forward, null);
        } else {
            uri = forwardPath;
        }*/
        uri = forwardPath;
        doForward(uri, request, response);
	}
	
	protected void doForward(String uri, HttpServletRequest request,
	        HttpServletResponse response)
	        throws IOException, ServletException {
	        RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);

	        if (rd == null) {
	            
	            System.out.println("500错误");

	            return;
	        }

	        rd.forward(request, response);
	    }
	
	protected ServletContext getServletContext() {
        return (servlet.getServletContext());
    }
	
	/**
	 * 执行业务返回重定向
	 * @param request
	 * @param response
	 * @param action
	 * @param form
	 * @param mapping
	 * @return
	 */
	private ActionForward processActionPerform(HttpServletRequest request,
			HttpServletResponse response, Action action, ActionForm form,
			ActionMapping mapping) {
		try {
			return (action.execute(mapping, form, request, response));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	protected Action processActionCreate(HttpServletRequest request,
	        HttpServletResponse response, ActionMapping mapping) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
		String className = mapping.getType();
		System.out.println("className==="+className);
		Action instance;
		
		synchronized (actions) {
			instance = (Action) actions.get(className);
			if (instance != null) {
				return (instance);
			}
			instance = (Action) RequestUtils.applicationInstance(className);

			actions.put(className, instance);
		}
		
		return instance;
	}

	 protected ActionForm processActionForm(HttpServletRequest request,
		        HttpServletResponse response, ActionMapping mapping) {
		 ActionForm instance = mapping.getActionForm();
		 if(instance != null){
			 return instance;
		 }else{
			 return null;
		 }
	 }

	
	/**
	 * 获取对应的action配置
	 * @param request
	 * @param response
	 * @param path
	 * @return
	 * @throws IOException
	 */
	protected ActionMapping processMapping(HttpServletRequest request,
	        HttpServletResponse response, String path){
		
		return actionMapping;
	}
	
	/**
	 * 设置国际化
	 * @param request
	 * @param response
	 */
	protected void processLocale(HttpServletRequest request,
	        HttpServletResponse response) {
	        

	        // Has a Locale already been selected?
	        HttpSession session = request.getSession();

	        if (session.getAttribute(LOCALE_KEY) != null) {
	            return;
	        }

	        // Use the Locale returned by the servlet container (if any)
	        Locale locale = request.getLocale();

	        if (locale != null) {
	           

	            session.setAttribute(LOCALE_KEY, locale);
	        }
	    }
	
	/**
	 * 获取请求路径
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 */
	protected String processPath(HttpServletRequest request,
	        HttpServletResponse response) {
	        String path;

	        

	        // For prefix matching, match on the path info (if any)
	        path = (String) request.getAttribute(INCLUDE_PATH_INFO);

	        if (path == null) {
	            path = request.getPathInfo();
	        }

	        if ((path != null) && (path.length() > 0)) {
	            return (path);
	        }

	        // For extension matching, strip the module prefix and extension
	        path = (String) request.getAttribute(INCLUDE_SERVLET_PATH);

	        if (path == null) {
	            path = request.getServletPath();
	        }

	        


	        int slash = path.lastIndexOf("/");
	        int period = path.lastIndexOf(".");

	        if ((period >= 0) && (period > slash)) {
	            path = path.substring(0, period);
	        }

	        return (path);
	    }
	

}
